using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;

public class DmValueGenerationStrategyConvention : IModelInitializedConvention, IConvention, IModelFinalizingConvention
{
	protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; }

	public DmValueGenerationStrategyConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies, [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies)
	{
		Dependencies = dependencies;
	}

	public virtual void ProcessModelInitialized(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
	{
		modelBuilder.HasValueGenerationStrategy(DmValueGenerationStrategy.IdentityColumn);
	}

	public virtual void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		foreach (IConventionEntityType entityType in modelBuilder.Metadata.GetEntityTypes())
		{
			foreach (IConventionProperty declaredProperty in entityType.GetDeclaredProperties())
			{
				DmValueGenerationStrategy? dmValueGenerationStrategy = null;
				string tableName = RelationalEntityTypeExtensions.GetTableName(entityType);
				if (tableName != null)
				{
					StoreObjectIdentifier storeObject2 = StoreObjectIdentifier.Table(tableName, RelationalEntityTypeExtensions.GetSchema(entityType));
					dmValueGenerationStrategy = declaredProperty.GetValueGenerationStrategy(in storeObject2);
					if (dmValueGenerationStrategy == DmValueGenerationStrategy.None && !IsStrategyNoneNeeded(declaredProperty, storeObject2))
					{
						dmValueGenerationStrategy = null;
					}
				}
				else
				{
					string viewName = RelationalEntityTypeExtensions.GetViewName(entityType);
					if (viewName != null)
					{
						StoreObjectIdentifier storeObject3 = StoreObjectIdentifier.View(viewName, RelationalEntityTypeExtensions.GetViewSchema(entityType));
						dmValueGenerationStrategy = declaredProperty.GetValueGenerationStrategy(in storeObject3);
						if (dmValueGenerationStrategy == DmValueGenerationStrategy.None && !IsStrategyNoneNeeded(declaredProperty, storeObject3))
						{
							dmValueGenerationStrategy = null;
						}
					}
				}
				if (dmValueGenerationStrategy.HasValue)
				{
					declaredProperty.Builder.HasValueGenerationStrategy(dmValueGenerationStrategy);
				}
			}
		}
		static bool IsStrategyNoneNeeded(IReadOnlyProperty property, StoreObjectIdentifier storeObject)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			object obj = default(object);
			if ((int)property.ValueGenerated == 1 && !RelationalPropertyExtensions.TryGetDefaultValue(property,  storeObject, out obj) && RelationalPropertyExtensions.GetDefaultValueSql(property,  storeObject) == null && RelationalPropertyExtensions.GetComputedColumnSql(property,  storeObject) == null && ((IReadOnlyTypeBase)property.DeclaringEntityType).Model.GetValueGenerationStrategy().GetValueOrDefault() == DmValueGenerationStrategy.IdentityColumn)
			{
				object obj2 = property.GetValueConverter();
				if (obj2 == null)
				{
					RelationalTypeMapping obj3 = RelationalPropertyExtensions.FindRelationalTypeMapping(property,  storeObject);
					obj2 = ((obj3 != null) ? ((CoreTypeMapping)obj3).Converter : null);
				}
				Type type = ((obj2 != null) ? ((ValueConverter)obj2).ProviderClrType.UnwrapNullableType() : null);
				if (type != null)
				{
					if (!type.IsInteger())
					{
						return type == typeof(decimal);
					}
					return true;
				}
				return false;
			}
			return false;
		}
	}
}
